package com.spsy.thread;



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

import java.sql.*;
import java.util.Random;
public class SimpleMultiThreadInsert {

    // 数据库配置 - 修改这里！
    private static final String URL = "jdbc:mysql://192.168.80.192:3306/ry_2302a_order?useUnicode=true&characterEncoding=UTF-8";
    private static final String USERNAME = "root";    // 改成你的用户名
    private static final String PASSWORD = "root";  // 改成你的密码

    // 插入配置
    private static final int TOTAL_RECORDS = 50000000;  // 500万条
    private static final int THREAD_COUNT = 8;         // 5个线程
    private static final int BATCH_SIZE = 10000;        // 每批插入1000条

    // 进度计数器
    private static final AtomicInteger progress = new AtomicInteger(0);

    public static void main(String[] args) {
        System.out.println("🚀 开始多线程插入 " + TOTAL_RECORDS + " 条订单数据...");
        System.out.println("📊 使用 " + THREAD_COUNT + " 个线程，每批 " + BATCH_SIZE + " 条");
        System.out.println("==================================================");

        long startTime = System.currentTimeMillis();

        try {
            // 创建线程池
            ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);

            // 计算每个线程处理的数据量
            int recordsPerThread = TOTAL_RECORDS / THREAD_COUNT;

            // 提交任务
            for (int i = 0; i < THREAD_COUNT; i++) {
                int start = i * recordsPerThread;
                int end = (i == THREAD_COUNT - 1) ? TOTAL_RECORDS : start + recordsPerThread;

                executor.execute(new InsertTask(i + 1, start, end));
            }

            // 关闭线程池，不再接受新任务
            executor.shutdown();

            // 等待所有任务完成
            while (!executor.isTerminated()) {
                Thread.sleep(1000); // 每秒检查一次

                // 显示进度
                int currentProgress = progress.get();
                double percent = (currentProgress * 100.0) / TOTAL_RECORDS;
                if (currentProgress % 100000 == 0) {
                    System.out.printf("📈 进度: %.1f%% [%d/%d]%n", percent, currentProgress, TOTAL_RECORDS);
                }
            }

            long endTime = System.currentTimeMillis();
            long totalTime = endTime - startTime;

            System.out.println("==================================================");
            System.out.println("✅ 插入完成！");
            System.out.println("⏰ 总耗时: " + totalTime + " 毫秒 (" + (totalTime / 1000.0) + " 秒)");
            System.out.println("⚡ 平均速度: " + (TOTAL_RECORDS / (totalTime / 1000.0)) + " 条/秒");

        } catch (Exception e) {
            System.err.println("❌ 发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 插入任务类
    static class InsertTask implements Runnable {
        private int taskId;
        private int startIndex;
        private int endIndex;
        private Random random = new Random();

        public InsertTask(int taskId, int startIndex, int endIndex) {
            this.taskId = taskId;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
        }

        @Override
        public void run() {
            Connection conn = null;
            PreparedStatement pstmt = null;

            try {
                // 1. 连接数据库
                conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
                conn.setAutoCommit(false); // 关闭自动提交，提高性能

                // 2. 准备SQL（包含order_no2字段）
                String sql = "INSERT INTO order_table (" +
                        "order_id, order_no2, user_id, product_id, quantity, " +
                        "price, status, create_time, update_time, remark" +
                        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

                pstmt = conn.prepareStatement(sql);

                int batchCount = 0;

                // 3. 循环插入数据
                for (int i = startIndex; i < endIndex; i++) {
                    // 设置参数值
                    setParameters(pstmt, i);

                    // 添加到批处理
                    pstmt.addBatch();
                    batchCount++;

                    // 批量提交
                    if (batchCount % BATCH_SIZE == 0) {
                        pstmt.executeBatch();
                        conn.commit();
                        pstmt.clearBatch();
                        batchCount = 0;

                        // 更新进度
                        progress.addAndGet(BATCH_SIZE);
                    }
                }

                // 提交剩余的数据
                if (batchCount > 0) {
                    pstmt.executeBatch();
                    conn.commit();
                    progress.addAndGet(batchCount);
                }

                System.out.println("✅ 任务" + taskId + " 完成，插入 " + (endIndex - startIndex) + " 条数据");

            } catch (Exception e) {
                System.err.println("❌ 任务" + taskId + " 出错: " + e.getMessage());
            } finally {
                // 4. 关闭资源
                try {
                    if (pstmt != null) pstmt.close();
                    if (conn != null) conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

        // 设置SQL参数的方法
        private void setParameters(PreparedStatement pstmt, int index) throws SQLException {
            long orderId = System.currentTimeMillis() + index; // 订单ID
            String orderNo2 = "ORDER2_" + System.currentTimeMillis() + "_" + index; // order_no2字段

            pstmt.setLong(1, orderId);                                      // order_id
            pstmt.setString(2, orderNo2);                                   // order_no2（无索引字段）
            pstmt.setLong(3, 10000 + index % 100000);                       // user_id
            pstmt.setLong(4, 20000 + index % 5000);                         // product_id
            pstmt.setInt(5, 1 + random.nextInt(10));                        // quantity
            pstmt.setDouble(6, 10.0 + random.nextDouble() * 990.0);         // price
            pstmt.setInt(7, random.nextInt(5));                             // status
            pstmt.setTimestamp(8, new Timestamp(System.currentTimeMillis() - random.nextInt(1000000000))); // create_time
            pstmt.setTimestamp(9, new Timestamp(System.currentTimeMillis() - random.nextInt(100000000)));  // update_time
            pstmt.setString(10, "测试订单-" + index);                        // remark
        }
    }
}